/**
 *
 */
package com.jhws.sys.user.service;

import java.util.*;

import javax.annotation.Resource;

import com.jhws.common.PropertiesReader;
import com.jhws.core.db.BaseDao;
import com.jhws.core.exception.BizException;
import com.jhws.sys.menu.bo.TblMenuDimBo;
import com.jhws.sys.params.bo.SysParamConstant;
import com.jhws.sys.params.service.SysParamService;
import com.jhws.sys.user.bo.UserCommsBo;
import com.jhws.sys.user.bo.UserPerms;
import com.jhws.util.AccountsUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import com.jhws.business.comm.bo.TblCommDimBo;
import com.jhws.sys.role.bo.TblRolemenuDimBo;
import com.jhws.sys.user.bo.TblUserDimBo;
import com.jhws.sys.menu.bo.MenuObject;
import com.jhws.util.security.CryptionData;
import com.jhws.common.base.bo.Global;
import com.jhws.business.comm.service.ITblCommDimService;
import com.jhws.sys.menu.service.ITblMenuDimService;
import com.jhws.sys.role.service.ITblRolemenuDimService;
import com.jhws.util.commUtil;

/**
 * @author wuyingbiao
 *
 */
public class TblUserDimServiceSpringImpl implements ITblUserDimService {

	@Resource
	private BaseDao BaseDao;

	@Resource
	private UserCommsService userCommsService;

	@Autowired
	private ITblMenuDimService IMenuDimService;

	@Autowired
	private ITblRolemenuDimService IRoleMenuService;

	@Autowired
	private ITblCommDimService ICommService;

	@Resource
	private SysParamService sysParamService;


	public void save(TblUserDimBo bo) throws Exception {
		BaseDao.saveOrUpdate(bo);
	}

	public List<TblUserDimBo> findTblUserDimByWhere(String whereClause)  {
		return BaseDao.findList("from TblUserDimBo "+whereClause);
	}

	public TblUserDimBo getUserByName(String username){
		String column = AccountsUtils.isChinaPhoneLegal(username)?"tel_num":"log_Name";
		List<TblUserDimBo> list = BaseDao.findList("from TblUserDimBo where "+column+" = '"+username+"'");
		if(!list.isEmpty()){
			return list.get(0);
		}
		return null;
	}

	public TblUserDimBo findTblUserDimById(String TblUserId) {
		return BaseDao.get(TblUserDimBo.class,TblUserId);
	}

	public void removeUserDim(String TblUserId) {
		BaseDao.delete(TblUserDimBo.class,TblUserId);
	}

	public boolean login(String loginName, String loginPwd) {
		try {
			loginPwd = (new CryptionData()).EncryptionStringData(loginPwd);
		} catch (Exception e) {
			e.printStackTrace();
		}

		TblUserDimBo bo = getUserByName(loginName);

		if (bo == null)
			return false;
		else if (loginPwd.equals(bo.getLogPwd()))
			return true;
		else
			return false;
	}

	public boolean findPassword(String emailAddress, String telNum) {
		List<TblUserDimBo> list = BaseDao.findList("from TblUserDimBo where email_address = '"+emailAddress+"' and tel_num = '"+telNum+"'");
		if(!list.isEmpty()){
			return true;
		}
		return false;
	}

	public TblUserDimBo getLoginUserInfo(String loginName) {
		List<TblUserDimBo> list = BaseDao.findList("from TblUserDimBo where log_name = '"+loginName+"'");
		if(!list.isEmpty()){
			return list.get(0);
		}
		return null;
	}


	public TblUserDimBo currentUser(){
		TblUserDimBo bo = (TblUserDimBo)RequestContextHolder
				.currentRequestAttributes()
				.getAttribute(TblUserDimBo.USER_INFO_REFERENCE, RequestAttributes.SCOPE_SESSION);
		return bo;
	}

	public List<MenuObject> getUserMenus(TblUserDimBo userInfo) throws Exception{
		@SuppressWarnings("unchecked")
		String roleCode = userInfo.getRoleCode();
		List<TblRolemenuDimBo> roleMenuList = IRoleMenuService.findTblRolemenuDimByWhere("where 1=1 and role_code = '"+roleCode+"'");
		List<MenuObject> menuList = IMenuDimService.getAllMenuObjects(1,null,roleMenuList,Global.TYPE_ROLE_MENUS);
		return menuList;
	}

	public List<TblCommDimBo> getUserComms(TblUserDimBo userInfo) throws Exception {
		String where = " where 1=1 ";
		if (SecurityUtils.getSubject().hasRole(Global.ROLE_SUPPER_ADMIN)) {
			return ICommService.findTblCommDimByWhere(where);
		} else {
            String commWhere = getUserCommsSqlStr(userInfo);
			where += " and comm_code in (" + commWhere + ")";
			return ICommService.findTblCommDimByWhere(where);
		}

	}

	@Override
	public String getUserCommsSqlStr(TblUserDimBo userInfo) {
        List<UserCommsBo> list = userCommsService.findUserCommsByName(userInfo.getLogName());
        String userComms = "";
        /* 如果用户不存在,可能是webapi过来的session用户 */
        if((list == null || list.size() == 0) && StringUtils.isNotEmpty(userInfo.getCommCode()))
			userComms = commUtil.commCodesToSqlStr(userInfo.getCommCode());
        else
			userComms = commUtil.userCommsToSqlStr(list);

        if(StringUtils.isEmpty(userComms) && !SecurityUtils.getSubject().hasRole(Global.ROLE_SUPPER_ADMIN))
        	userComms = "'-1'";//不允许用户绑定小区为空,sql查询in语句会出错

        return userComms;
	}

	public Map findUserList(String logName,String commCode,String roleName) throws Exception {
		String whereClause = "1=1 ";

		if (StringUtils.isNotEmpty(logName)) {
			whereClause += " and log_name like '%" + logName + "%'";
		}

        if (StringUtils.isNotEmpty(commCode)) {
			List<UserCommsBo> userCommsBoList = userCommsService.findUserCommsByWhere(" where comm_code = '"+commCode+"'");
			String logNameStr = "";

			for(int i=0;i<userCommsBoList.size();i++){
				logNameStr+="'"+userCommsBoList.get(i).getUserName()+"'";
				if(i+1!=userCommsBoList.size())
					logNameStr+=",";
			}
			whereClause += userCommsBoList.size()>0?" and log_name in ("+logNameStr+")":"";
        }

        if(StringUtils.isNotEmpty(roleName)){
            whereClause += " and role_name = '"+roleName+"'";
        }

        if(SecurityUtils.getSubject().hasRole(Global.ROLE_SEC_LEVEL_ADMIN)){
            whereClause += " and creater ='"+SecurityUtils.getSubject().getPrincipal().toString()+"'";
        }

        whereClause += " order by last_log_time desc";
		return BaseDao.queryPage("from TblUserDimBo where "+whereClause);
	}

	/**
	 * 检测当前账号是否具有某个小区的操作权限
	 * 假如传入空值,则返回一个该账户合法的小区编号,假如传入的小区不为空且无此权限，则抛出异常
	 * @param commCode
	 * @return
	 * @throws Exception
	 */
	@Override
	public String checkCommCodePermission(String commCode) throws Exception {
        String userCommCode = getUserCommsSqlStr(currentUser());

		/* 当前账号不是管理员，必须要校验获取的小区是否具有权限 */
        if(!userCommCode.equals("'-1'") && StringUtils.isNotEmpty(userCommCode) && !userCommCode.contains(commCode)){
            throw new BizException("-1","","您没有访问"+commCode+"小区的权限!");
        }

        if(StringUtils.isEmpty(commCode) && StringUtils.isNotEmpty(userCommCode)){
            String [] comms = userCommCode.split(",");
            return comms[0].replace("'","");
        }

		return commCode;
	}

	/**
	 * 查询出当前用户绑定的权限字段
	 * @param userCode
	 * @return
	 */
	public List<String> findUserPerms(String userCode){
		List<Map> list = BaseDao.findList("select new map(m.permission as permission,up.endDate as endDate) " +
				"from UserPerms as up,TblMenuDimBo as m " +
				"where  up.userCode = '"+userCode+"' and up.menuCode = m.menuCode and m.permission IS NOT NULL");

		List<String> retList = new ArrayList();
		Date now = new Date();
		for(Map map : list){
			Date endDate = (Date)map.get("endDate");
			if(endDate == null || endDate.getTime() > now.getTime())
			    retList.add((String)map.get("permission"));
		}
		return retList;
	}

	/**
	 * 生成一些平台相关的权限，用于不同的平台显示不同的功能，避免报错
	 * 主要给一些私有部署的平台使用
	 * @return
	 */
	public List<String> getPlatformPerms(){
		List<String> retList = new ArrayList<String>();
		String AliLogEndpoint = PropertiesReader.getProperty("logAliEndpoint");
		if(StringUtils.isNotEmpty(AliLogEndpoint) && !AliLogEndpoint.startsWith("$"))
			retList.add("hasAliLog");

        if(sysParamService.getParam(SysParamConstant.SUBPARAM_NO_DASHBOARD) != null)
            retList.add(SysParamConstant.SUBPARAM_NO_DASHBOARD);
		return retList;
	}

	/**
	 * 保存用户权限
	 * @param userPerms
	 */
	@Override
	public void saveUserPerms(UserPerms userPerms) {
		BaseDao.saveOrUpdate(userPerms);
	}

	/**
	 * 查询用户对于的权限
	 * @param userCode
	 * @return
	 */
	@Override
	public List<TblMenuDimBo> findUserPermsObjects(String userCode) {
        return BaseDao.findList("select new TblMenuDimBo(m.menuCode as menuCode, m.permission as permission, m.type as type) " +
                "from UserPerms as up,TblMenuDimBo as m " +
                "where  up.userCode = '"+userCode+"' and up.menuCode = m.menuCode and m.permission IS NOT NULL");
	}
}
